﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpVersion_2
{
    class IEnumerableMethod
    {
        static IEnumerable<int> CreateSimpleIterator()
        {
            yield return 10;
            for (int i = 0; i < 3; i++)
            {
                yield return i;
            }
            yield return 20;
        }

        /**
         * 可以把 IEnumerable 想象成一本书，把 IEnumerator 想象成书签。
         * 一本书可以同时有多个书签，一个书签的移动不会改变书和其他书签的状态，
         * 但是书签自身的状态（它在书中的位置）会改变。
         * */
        public static void DeferredEXE()
        {
            //调用迭代器
            IEnumerable<int> enumerable = CreateSimpleIterator();
            //从迭代器（迭代的序列）里获取枚举器（序列的一个游标）
            using (IEnumerator<int> enumerator = enumerable.GetEnumerator())
            {
                //直到调用代码开始迭代序列之后，迭代器的代码才开始执行。
                while (enumerator.MoveNext())   //如果存在下一个元素，则移动到下一个元素
                {
                    int value = enumerator.Current; // 获取当前值
                    Console.WriteLine(value);
                }
            }
        }

        //斐波那契数列
        static IEnumerable<int> Fobonacci()
        {
            int current = 0;
            int next = 1;

            while (true)
            {
                yield return current;
                int oldNum = current;
                current = next;
                next = current + oldNum;
            }
        }

        public static void PrintFobonacci()
        {
            foreach (var item in Fobonacci())
            {
                Console.WriteLine(item);
                if (item > 1000)
                {
                    break;
                }
            }
        }

        //逐行读取文件内容
        static IEnumerable<string> ReadLines(string path)
        {
            using (TextReader reader = File.OpenText(path))
            {
                string line;
                while((line = reader.ReadLine()) != null)
                {
                    yield return line;
                }
            }
        }
    }

        
}
